package cn.cqs.redisitem.shiro.config;

import cn.cqs.redisitem.shiro.CustomRealm;
import cn.cqs.redisitem.shiro.CustomSubjectFactory;
import cn.cqs.redisitem.shiro.JwtShiroFilter;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.DefaultSubjectFactory;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author : cqs
 * @decpresioin :
 * @date : 2020-09-11 6:23
 */

@Configuration
public class ShiroConfig {
    /**
     * 功能描述 :自定义的SubjectFacotry关闭session
     *
     * @return DefaultSubjectFactory
     * @author cqs
     * @date 2020/9/11
     */

    @Bean
    public DefaultSubjectFactory subjectFactory() {
        return new CustomSubjectFactory();
    }

    @Bean
    public Realm realm() {
        return new CustomRealm();
    }


    /**
     * 功能描述 :1.配置Shiro的SecurityManager
     *
     * @return org.apache.shiro.web.mgt.DefaultWebSecurityManager
     * @author cqs
     * @date 2020/9/11
     */
    @Bean("securityManager")
    public DefaultWebSecurityManager securityManager() {
//        shiro的核心类SecurityManger所有类控制中心
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//        关闭ShiroDAO功能
        DefaultSubjectDAO defaultSubjectDAO = new DefaultSubjectDAO();
//        关闭session存储
        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
        defaultSubjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
//
//        禁止调用subject.getssion()
        securityManager.setSubjectFactory(subjectFactory());
//        禁用 rememberMe
//        securityManager().setRememberMeManager(null);
//        必须引入自定义的领域类Realm
        securityManager.setRealm(realm());
        return securityManager;
    }

    /**
     * 功能描述 :shiroFilterFactory用来管理SecurityManager,及过滤器及过滤器链条
     *
     * @return org.apache.shiro.spring.web.ShiroFilterFactoryBean
     * @author cqs
     * @date 2020/9/11
     */

    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());
//        自定义过滤器
        Map<String, Filter> filterMap = new HashMap<>();
        filterMap.put("jwtShiroFilter", new JwtShiroFilter());
        shiroFilterFactoryBean.setFilters(filterMap);
//       TODO 管理Filter链条
        Map<String, String> filterRulesChainMap = new HashMap<>();
//        匿名访问
        filterRulesChainMap.put("/tologin", "noSessionCreation,anon");
        filterRulesChainMap.put("/exception", "noSessionCreation,anon");
        filterRulesChainMap.put("/login", "noSessionCreation,anon");
        filterRulesChainMap.put("/error", "noSessionCreation,anon");
        filterRulesChainMap.put("/findAllUser", "anon");
        filterRulesChainMap.put("/pc/**", "anon");
        filterRulesChainMap.put("/sysregister", "anon");
//        filterRulesChainMap.put("/todenied", "noSessionCreation,anon");
//       自定义filter过滤规则
        filterRulesChainMap.put("/**", "jwtShiroFilter");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterRulesChainMap);
//        shiroFilterFactoryBean.setLoginUrl("/tologin");
//        shiroFilterFactoryBean.setSuccessUrl("/indexpage");
//        shiroFilterFactoryBean.setUnauthorizedUrl("/todenied");

        return shiroFilterFactoryBean;
    }

    @Bean("lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    /**
     * 功能描述 : 开启shiro注解 @RequiresRoles，@RequiresPermissions等
     *
     * @return org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor
     * @author cqs
     * @date 2020/9/11
     */
    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
        // 强制指定注解的底层实现使用 cglib 方案
        proxyCreator.setProxyTargetClass(true);
        return proxyCreator;
    }

    @Bean
    protected AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }

}
